package it.polimi.digitalstate.manager;

import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import it.polimi.digitalstate.dto.*;
import it.polimi.digitalstate.entities.Election;

/**
 * This class is create to inglobe all the needed checking for
 * - create a party
 * - ask to join
 * - vote for a request
 * - election vote
 * - ...
 * in such the way that the code is more organized and - when in the debugging testing -  it is easy to hide this kind of constraints
 * @author Samuele
 *
 */
public class PreconditionCheck {

	public static boolean canCreateParty(CitizenDTO citizen, EntityManager em){
		return !isAMember(citizen,em) && !hasPendingRequest(citizen,em) && rightCandidacyTime(em);
	}
	public static boolean canRequestParty(CitizenDTO citizen, EntityManager em){
		return !isAMember(citizen,em) && !hasPendingRequest(citizen,em) && rightCandidacyTime(em);
	}
	public static boolean canAccessToRequestList(CitizenDTO citizen, PartyDTO party, EntityManager em){
		return isMemberOf(citizen, party, em);
	}
	public static boolean rightElectionTime(EntityManager em){
		Date todaydate = new Date();
		Query q = em.createNamedQuery("election_getElection");
		q.setParameter("todaydate", new java.sql.Date(todaydate.getTime()));
		return !q.getResultList().isEmpty();
	}
	public static boolean rightCandidacyTime(EntityManager em){
		Date todaydate = new Date();
		Query q = em.createNamedQuery("election_getCandidacy");
		q.setParameter("todaydate", new java.sql.Date(todaydate.getTime()));
		return !q.getResultList().isEmpty();
	}
	public static Election getCurrentElection(EntityManager em){
		Date todaydate = new Date();
		Query q = em.createNamedQuery("election_getElectionWeak");
		Date today = new java.sql.Date(todaydate.getTime());
		q.setParameter("todaydate", today );
		//TODO add some check and throws Exception
		System.out.println("getCurrentElection " + today.toString());
		if(q.getResultList().toArray().length>0)
			return (Election)q.getResultList().get(0);
		else
			return null;
	}
	public static boolean hasPendingRequest(CitizenDTO citizen, EntityManager em){
		Query q = em.createNamedQuery("joinrequest_getByCitizen");
		q.setParameter("citizen",DTOEntityTransformer.getEntity(em, citizen));
		return q.getResultList().toArray().length!=0;
	}
	public static boolean isAMember(CitizenDTO citizen, EntityManager em){
		Query q = em.createNamedQuery("membership_getByCitizen");
		q.setParameter("member",DTOEntityTransformer.getEntity(em, citizen));
		return q.getResultList().toArray().length!=0;
	}
	public static boolean isMemberOf(CitizenDTO citizen, PartyDTO party,EntityManager em){
		return false;
	}
	
	// election methods
	
	public static boolean correctElectionDates(ElectionDTO election_dto, EntityManager em)
	{
		Date earliestdate = new Date();
		earliestdate = (!election_dto.getCandidacystartdate().after(election_dto.getElectionstartdate()))? election_dto.getCandidacystartdate():election_dto.getElectionstartdate();
		Query q = em.createNamedQuery("election_getOverlappingElection");
		q.setParameter("earliestdate", new java.sql.Date(earliestdate.getTime()));
		return q.getResultList().isEmpty();	}
	
	// JoinVote methods
	
	public static boolean canJoinVote (CitizenDTO citizen, JoinrequestDTO joinrequest, EntityManager em) {
		Query q = em.createNamedQuery("joinvote_votedbefore");
		q.setParameter("citizen",DTOEntityTransformer.getEntity(em, citizen));
		q.setParameter("joinrequest",DTOEntityTransformer.getEntity(em, joinrequest));
		return q.getResultList().toArray().length==0;
	}
	
	// election vote methods
	public static boolean hasElectionVoted (CitizenDTO citizen, EntityManager em) {
		Query q = em.createNamedQuery("electionvote_votedbefore");
		q.setParameter("citizen",DTOEntityTransformer.getEntity(em, citizen));
		q.setParameter("election", getCurrentElection(em));
		return q.getResultList().toArray().length!=0;
	}
}
